use std::fmt::{self, Formatter};
use std::hash::Hash;
use std::hash;
+use std::path::Path;
use std::sync::Arc;
use semver;
}),
}
}
+
+ pub fn stable_hash<'a>(&'a self, workspace: &'a Path) -> PackageIdStableHash<'a> {
+ PackageIdStableHash(&self, workspace)
+ }
+}
+
+pub struct PackageIdStableHash<'a>(&'a PackageId, &'a Path);
+
+impl<'a> Hash for PackageIdStableHash<'a> {
+ fn hash<S: hash::Hasher>(&self, state: &mut S) {
+ self.0.inner.name.hash(state);
+ self.0.inner.version.hash(state);
+ self.0.inner.source_id.stable_hash(self.1, state);
+ }
}
impl fmt::Display for PackageId {
use std::cmp::{self, Ordering};
use std::collections::hash_map::{HashMap, Values, IterMut};
use std::fmt::{self, Formatter};
-use std::hash;
+use std::hash::{self, Hash};
use std::path::Path;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT};
}
self.inner.url.to_string() == CRATES_IO
}
+
+ pub fn stable_hash<S: hash::Hasher>(&self, workspace: &Path, into: &mut S) {
+ if self.is_path() {
+ if let Ok(p) = self.inner.url.to_file_path().unwrap().strip_prefix(workspace) {
+ self.inner.kind.hash(into);
+ p.to_str().unwrap().hash(into);
+ return
+ }
+ }
+ self.hash(into)
+ }
}
impl PartialEq for SourceId {
// The hash of SourceId is used in the name of some Cargo folders, so shouldn't
// vary. `as_str` gives the serialisation of a url (which has a spec) and so
// insulates against possible changes in how the url crate does hashing.
-impl hash::Hash for SourceId {
+impl Hash for SourceId {
fn hash<S: hash::Hasher>(&self, into: &mut S) {
self.inner.kind.hash(into);
match *self.inner {
let name = unit.pkg.package_id().name();
match self.target_metadata(unit) {
Some(meta) => format!("{}-{}", name, meta),
- None => format!("{}-{}", name, util::short_hash(unit.pkg)),
+ None => format!("{}-{}", name, self.target_short_hash(unit)),
}
}
self.build_config.requested_target.as_ref().map(|s| &s[..])
}
+ /// Get the short hash based only on the PackageId
+ /// Used for the metadata when target_metadata returns None
+ pub fn target_short_hash(&self, unit: &Unit) -> String {
+ let hashable = unit.pkg.package_id().stable_hash(self.ws.root());
+ util::short_hash(&hashable)
+ }
+
/// Get the metadata for a target in a specific profile
/// We build to the path: "{filename}-{target_metadata}"
/// We use a linking step to link/copy to a predictable filename
// Unique metadata per (name, source, version) triple. This'll allow us
// to pull crates from anywhere w/o worrying about conflicts
- unit.pkg.package_id().hash(&mut hasher);
+ unit.pkg.package_id().stable_hash(self.ws.root()).hash(&mut hasher);
// Add package properties which map to environment variables
// exposed by Cargo
use core::{Profile, Profiles, Workspace};
use core::shell::ColorChoice;
use util::{self, ProcessBuilder, machine_message};
-use util::{Config, internal, profile, join_paths, short_hash};
+use util::{Config, internal, profile, join_paths};
use util::errors::{CargoResult, CargoResultExt};
use util::Freshness;
cmd.arg("-C").arg(&format!("extra-filename=-{}", m));
}
None => {
- cmd.arg("-C").arg(&format!("metadata={}", short_hash(unit.pkg)));
+ cmd.arg("-C").arg(&format!("metadata={}", cx.target_short_hash(unit)));
}
}